﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Net.Mail;
using System.Reflection;


namespace MFD.SharePoint.Notifications
{
   
    [Serializable]
    [XmlRoot(Namespace = "", IsNullable = true, ElementName = "EmailItem")]
	public class EmailItem
    {



        #region Variables
        private string _name;

        private string _to;
        private string _cc;
        private string _bcc;
        

        private string _subject;
        private string _body;
        private MailPriority _priority;

        private string _replyToAdress;

       

        #endregion

        #region Constructor
        public EmailItem()
        { }
        private EmailItem(string name, string subject, string body)
            : this()
        {
            _name = name;
            _subject = subject;
            _body = body;
        }
        #endregion

        #region Properties       
        
        public string To
        {
            get { return _to; }
            set { _to = value; }
        }

        public string CC
        {
            get { return _cc; }
            set { _cc = value; }
        }

        public string BCC
        {
            get { return _bcc; }
            set { _bcc = value; }
        }

        public MailPriority Priority
        {
            get { return _priority; }
            set { _priority = value; }
        }
        public string ReplyToAdress
        {
            get { return _replyToAdress; }
            set { _replyToAdress = value; }
        }

        [XmlAttribute("name")]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        [XmlElement("Subject")]
        public string Subject
        {
            get { return _subject; }
            set { _subject = value; }
        }
        [XmlElement("Body")]
        public string Body
        {
            get { return _body; }
            set { _body = value; }
        }
        #endregion

        #region Methods

        

        internal static EmailItem Create(EmailTemplate template, List<object> values)
        {
            EmailItem item = new EmailItem();

            item.Subject = template.Subject;
            item.Body = template.Body;

            foreach (object v in values)
            {
                //replace all the fields with real data for subject
                item.Subject = Replace(item.Subject, v);
                //replace all the fields with real data for the body
                item.Body = Replace(item.Body, v);
            }

            return item;
        }

        private static string Replace(string source, object v)
        {
            if (v == null)
                return source;

            string ret = source;
                //get all public properties
                foreach (PropertyInfo prop in v.GetType().GetProperties())
                {
                    string tagName;
                    //check for the TagNameAttribute

                    TagNameAttribute tag=null;
                    var attributes = prop.GetCustomAttributes(typeof(TagNameAttribute), true);
                    if (attributes.Length>0)
                        tag =attributes[0] as TagNameAttribute;
                    if (tag != null)
                    {
                        tagName = string.Format("[{0}]",tag.TagName);
                    }
                    else
                        tagName = string.Format("[{0}]", prop.Name);
                    string val = string.Format("{0}", prop.GetValue(v,null)); //TODO check for indexed properties (arrays, lists, IEnumerable, etc)
                    ret = ret.Replace(tagName, val);
                }
            return ret;
        }

        

        #endregion

        public MailMessage GetEmailMessage()
        {
            MailMessage msg = new MailMessage();

            foreach (var email in GetEmails(this.To))
                msg.To.Add(email);

            if (!string.IsNullOrEmpty(_cc))
                foreach (var email in GetEmails(_cc))
                    msg.CC.Add(email);

            if (!string.IsNullOrEmpty(_bcc))
                foreach (var email in GetEmails(_bcc))
                    msg.Bcc.Add(email);

            
            msg.Subject = this.Subject;
            msg.Body = this.Body;
            msg.IsBodyHtml = true;           
            msg.Priority = this.Priority;

            return msg;
        }       

        private List<MailAddress> GetEmails(string addr)
        {
            List<MailAddress> ret = new List<MailAddress>();

            if (addr.Contains(";") | addr.Contains(","))
            {
                string tokens = ";,";
                string[] addresses = addr.Split(tokens.ToCharArray());
                foreach (string address in addresses)
                {
                    if (!address.Equals(string.Empty))
                        ret.Add(new MailAddress(address));
                }
            }
            else
                ret.Add(new MailAddress(addr));

            return ret;
        }

        internal static EmailItem Create(EmailTemplate template, object values)
        {
            EmailItem item = new EmailItem();

            
            //replace all the fields with real data for subject
            item.Subject = Replace(template.Subject, values);

            //replace all the fields with real data for the body
            item.Body = Replace(template.Body, values);

            return item;
        
        }

        
    }
}
